package com.knowledgegraph.neo4j.service.impl;

import com.knowledgegraph.neo4j.entity.GraphRelation;
import com.knowledgegraph.neo4j.repository.GraphEntityRepository;
import com.knowledgegraph.neo4j.repository.GraphRelationRepository;
import com.knowledgegraph.neo4j.service.Neo4jRelationService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Neo4j 关系服务实现
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class Neo4jRelationServiceImpl implements Neo4jRelationService {
    
    private final GraphRelationRepository graphRelationRepository;
    private final GraphEntityRepository graphEntityRepository;
    
    @Override
    @Transactional
    public GraphRelation createRelation(Long sourceId, Long targetId, String type, String description,
                                       Double strength, Double confidence, Long graphId, String creator) {
        log.info("创建关系: {} -> {}, 类型: {}", sourceId, targetId, type);
        
        return graphRelationRepository.createRelation(sourceId, targetId, type, description,
                strength, confidence, graphId, creator);
    }
    
    @Override
    @Transactional
    public GraphRelation updateRelation(Long relationId, String type, String description,
                                       Double strength, Double confidence) {
        log.info("更新关系: {}", relationId);
        
        return graphRelationRepository.updateRelation(relationId, type, description, strength, confidence);
    }
    
    @Override
    @Transactional
    public void deleteRelation(Long relationId) {
        log.info("删除关系: {}", relationId);
        graphRelationRepository.deleteRelation(relationId);
    }
    
    @Override
    public List<Map<String, Object>> findByGraphId(Long graphId) {
        return graphRelationRepository.findByGraphId(graphId);
    }
    
    @Override
    public List<Map<String, Object>> findByType(String type) {
        return graphRelationRepository.findByType(type);
    }
    
    @Override
    public List<GraphRelation> findRelationsBetween(Long sourceId, Long targetId) {
        return graphRelationRepository.findRelationsBetween(sourceId, targetId);
    }
    
    @Override
    public Map<String, Object> getRelationStatistics(Long graphId) {
        List<Map<String, Object>> relations = graphRelationRepository.findByGraphId(graphId);
        
        Map<String, Object> statistics = new HashMap<>();
        statistics.put("totalCount", relations.size());
        statistics.put("typeCount", relations.stream()
                .map(r -> ((GraphRelation) r.get("r")).getType())
                .distinct()
                .count());
        statistics.put("strongRelationCount", relations.stream()
                .filter(r -> {
                    GraphRelation relation = (GraphRelation) r.get("r");
                    return relation.getStrength() != null && relation.getStrength() > 0.8;
                })
                .count());
        
        return statistics;
    }
    
    @Override
    public List<Map<String, Object>> getRelationTypeDistribution(Long graphId) {
        return graphRelationRepository.countRelationsByType(graphId);
    }
    
    @Override
    public List<Map<String, Object>> getEntityRelations(Long entityId) {
        return graphRelationRepository.findEntityRelations(entityId);
    }
    
    @Override
    public List<Map<String, Object>> getStrongRelations(Long graphId, Double threshold) {
        if (threshold == null) {
            threshold = 0.8;
        }
        return graphRelationRepository.findStrongRelations(graphId, threshold);
    }
    
    @Override
    @Transactional
    public List<GraphRelation> batchCreateRelations(List<Map<String, Object>> relationData) {
        log.info("批量创建关系: {} 个", relationData.size());
        
        // 这里需要根据实际的数据结构来实现批量创建
        // 暂时返回空列表，实际实现时需要遍历relationData并调用createRelation
        return new ArrayList<>();
    }
    
    @Override
    public Map<String, Object> getGraphStructure(Long graphId) {
        List<Map<String, Object>> structure = graphEntityRepository.findGraphStructure(graphId);
        
        Map<String, Object> result = new HashMap<>();
        result.put("nodes", structure.stream().map(s -> s.get("e")).distinct().collect(Collectors.toList()));
        result.put("edges", structure.stream().map(s -> s.get("r")).collect(Collectors.toList()));
        result.put("nodeCount", structure.stream().map(s -> s.get("e")).distinct().count());
        result.put("edgeCount", structure.size());
        
        return result;
    }
    
    @Override
    public List<Map<String, Object>> findShortestPath(Long startId, Long endId) {
        return graphEntityRepository.findShortestPath(startId, endId);
    }
}